dbt Cloud CLIとSQLFluffとGitHub Actionsを用いて、プルリクエスト発行時に自動フォーマッティングしてみた
さがらです。
dbt Cloud CLIとSQLFluffとGitHub Actionsを用いて、プルリクエスト発行時に自動フォーマッティングしてみたので、本記事でまとめてみます。
背景
なぜ「dbt Cloud CLIとSQLFluffとGitHub Actionsを用いて、プルリクエスト発行時に自動フォーマッティング」したいと考えたのかと言うと、「dbt CloudではSQLFluffを使ったフォーマッティングできる機能はあるものの、手動でボタンを押してファイル1つ1つに対してフォーマッティング行うしかないため」です。
これがdbt Coreだと、pre-commitなどを併用してローカルでの開発時にコミットのタイミングでフォーマッティングを自動で行うことができるのですが、dbt Cloudではpre-commitのような機能がありません。
そこで、dbt Cloudで開発を行って自動でフォーマッティングする一つの方法として「dbt Cloud CLIとSQLFluffとGitHub Actionsを用いて、プルリクエスト発行時に自動フォーマッティング」というアイデアに至りました。
(ちょうどよく2024年7月にdbt Cloud CLI経由でSQLFluffが実行できるようになったので、これも使ってみます。これを使うことで、GitHub Actionsでdbt Coreを使わずに済むため、profiles.yml
などの定義が不要となり楽になります。)
懸念点
ただし、今回の実装には以下の懸念点もあります。ご利用の際はこのあたりのリスクも考慮した上でご利用ください。
- 良くも悪くも
models
配下のすべてのSQLファイルが定めたSQLFluffのルールに沿ってフォーマッティングされてしまう - 今回検証したSQLファイルが少なかったこともあるため動作速度に問題はなかったが、ファイルが多い場合の動作速度がネックになる可能性がある
事前準備:SQLFluff用のファイルの設定
SQLFluffを使用するための各種ファイルを設定していきます。
.sqlfluff
ファイルをdbt projectのルート階層に追加します。内容はこちらの公式Docを参考にし、dbtのテンプレートを使用するようにしました。
[sqlfluff]
templater = dbt
# This change (from jinja to dbt templater) will make linting slower
# because linting will first compile dbt code into data warehouse code.
runaway_limit = 10
max_line_length = 80
indent_unit = space
[sqlfluff:indentation]
tab_space_size = 4
[sqlfluff:layout:type:comma]
spacing_before = touch
line_position = trailing
[sqlfluff:rules:capitalisation.keywords]
capitalisation_policy = lower
[sqlfluff:rules:aliasing.table]
aliasing = explicit
[sqlfluff:rules:aliasing.column]
aliasing = explicit
[sqlfluff:rules:aliasing.expression]
allow_scalar = False
[sqlfluff:rules:capitalisation.identifiers]
extended_capitalisation_policy = lower
[sqlfluff:rules:capitalisation.functions]
capitalisation_policy = lower
[sqlfluff:rules:capitalisation.literals]
capitalisation_policy = lower
[sqlfluff:rules:ambiguous.column_references] # Number in group by
group_by_and_order_by_style = implicit
次に、.sqlfluffignore
ファイルを下記の内容で追加します。
dbt_packages/
macros/
seeds/
target/
dbt Cloud CLIのConfiguration FileをGitHubのリポジトリにSecretとして登録
dbt Cloud CLIをGitHub Actions経由で動かすためには、ランナーの~/.dbt/
にdbt_cloud.yml
を作る必要があります。
dbt_cloud.yml
にはtoken情報が含まれるため、GitHubのリポジトリでSecretとして登録しておき、GitHub Actionsでジョブ実行時にSecretを参照して~/.dbt/
にdbt_cloud.yml
を作るようにしていきます。
まず、対象のdbt projectでDevelop
→Configure Cloud CLI
を押します。
表示された画面で、Python
を押した後に、Download CLI configuration file
を押します。(Python
を押さなくてもよいはずですが、GitHub Actionsで今回pipを使ってインストールするため、念の為押しています。)
ダウンロードしたdbt_cloud.ymlを加工し、必要なdbt projectの情報だけが含まれるように編集します。完成形としては下図のようになります。
加工が終わったら、そのファイルの内容をすべて、GitHubの対象リポジトリのActions secrets and variables
からSecretとして登録しておきます。
GitHub Actionsの設定
まず、dbt projectのルート階層で.github/workflows/
というフォルダを作ります。
次に、作成したフォルダ内で任意のyamlファイルを作成します。
作成したyamlファイルの中で、下記のコードを入力します。(なお、このコードの作成にあたってはこちらのPyhonコードの自動フォーマットの記事の内容を参考にさせていただきました。)
name: SQLFluff Formatting
on:
pull_request:
types: [opened, synchronize] # プルリクエストがオープン、更新された場合にトリガー
jobs:
formatter:
name: formatter
runs-on: ubuntu-latest # Ubuntu Linux 上で実行
permissions:
contents: write # コンテンツに対する書き込み権限を設定
steps:
- name: Checkout Repository
uses: actions/checkout@v4 # GitHubリポジトリからコードをチェックアウト
with:
ref: ${{ github.head_ref }} # GitHubヘッドリファレンスを指定。開発をしたプルリクエスト元のブランチが参照される
- name: Set up Python
uses: actions/setup-python@v4 # Python環境のセットアップ
with:
python-version: "3.12" # 使用するPythonバージョンを指定
- name: Authenticate using service account
run: |
mkdir -p ~/.dbt # .dbtディレクトリを作成
echo "$KEYFILE" > ~/.dbt/dbt_cloud.yml # secretとして登録したdbt_cloud.ymlを元に、ランナーでもdbt_cloud.ymlを作成
shell: bash
env:
KEYFILE: ${{secrets.DBT_CLOUD_CLI_CONFIG_YAML}}
- name: Install Dependencies
run: |
python -m pip install --upgrade pip # pipをアップグレード
pip install dbt --no-cache-dir # dbt Cloud CLIをインストール
- name: SQLFluff Fix # sqlfluffを使用してコードをフォーマッティング
run: dbt sqlfluff fix ./models/* --dialect snowflake # sqlfluffをmodelsフォルダ配下の.sqlファイルに適用
- name: Auto Commit
uses: stefanzweifel/git-auto-commit-action@v5 # 自動コミットアクションを使用
with:
commit_message: Apply Code Formatter(SQLFluff) # コミットメッセージを指定
挙動を確かめてみた
実際にdbt Cloud経由で開発を行い、SQLFluffを用いた自動フォーマッティングがされるかを確かめてみます。
まず、stg_customers.sql
を下記のようにインデントや大文字小文字が入り乱れているコードにしたうえで、コミットします。
この状態で、dbt Cloud経由でプルリクエストを発行します。
すると、先程ymlで定義したジョブがGitHub Actions経由で実行されます。
この後でプルリクエストに含まれるstg_customers.sql
を見ると、無事にフォーマッティングされた状態でコミットされていました!
最後に
dbt Cloud CLIとSQLFluffとGitHub Actionsを用いて、プルリクエスト発行時に自動フォーマッティングする方法についてまとめてみました。
プルリクエスト時の自動フォーマッティングは賛否分かれるかもしれませんが、dbt Cloud CLIをGitHub Actionsに組み込む方法については汎用的に使えると思います。一部でも本記事の内容が参考になっていると嬉しいです!